package com.yimi.policyservice.service.impl;

import cn.hutool.core.lang.UUID;
import com.github.pagehelper.Page;
import com.yimi.policyservice.common.expetion.ApiException;
import com.yimi.policyservice.dao.policy.*;
import com.yimi.policyservice.dto.product.DisabilitiesProductDto;
import com.yimi.policyservice.dto.product.PolicyItemDto;
import com.yimi.policyservice.dto.product.PolicyProductDto;
import com.yimi.policyservice.dto.product.PolicySuppRuleDto;
import com.yimi.policyservice.entity.base.optr.OptrComp;
import com.yimi.policyservice.entity.base.policy.*;
import com.yimi.policyservice.param.product.ProductParam;
import com.yimi.policyservice.repository.*;
import com.yimi.policyservice.service.CaseService;
import com.yimi.policyservice.utils.BeanHelper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class CaseServiceImp implements CaseService {

    @Autowired
    private PolicySocialProductRepository policySocialProductRepository ;

    @Autowired
    private PolicyAddressRepository policyAddressRepository ;

    @Autowired
    private CompRepositroy compRepositroy ;

    @Autowired
    private PolicySocialProductMapperCustom policySocialProductMapperCustom ;

    @Autowired
    private PolicySocialItemRepository policySocialItemRepository ;

    @Autowired
    private PolicySocialSuppRuleRepository policySocialSuppRuleRepository ;

    @Autowired
    private PolicySocialSuppRuleMapperCustom policySocialSuppRuleMapperCustom ;

    @Autowired
    private PolicyAccfundProductRepository policyAccfundProductRepository ;

    @Autowired
    private PolicyAccfundProductMapperCustom policyAccfundProductMapperCustom ;

    @Autowired
    private  PolicyAccfundItemRepository policyAccfundItemRepository ;

    @Autowired
    private PolicyAccfundSuppRuleRepository policyAccfundSuppRuleRepository ;

    @Autowired
    private PolicyAccfundSuppRuleMapperCustom policyAccfundSuppRuleMapperCustom ;

    @Autowired
    private PolicyDisabilitiesProductRepository policyDisabilitiesProductRepository ;

    @Autowired
    private PolicyDisabilitiesProductMapperCustom policyDisabilitiesProductMapperCustom ;
    @Override
    public PolicyProductDto createSocialProduct(PolicyProductDto bean) {
        PolicySocialProduct policySocialProduct = new PolicySocialProduct();
        PolicyAddr addr = policyAddressRepository.findById(bean.getAddrId()).get();
        bean.setAddrName(addr.getAddrName());
        OptrComp optrComp  = compRepositroy.findById(bean.getOptrCompId()).get();
        bean.setOptrCompName(optrComp.getName());
        bean.setOptrCompCode(optrComp.getCode());
        BeanUtils.copyProperties(bean,policySocialProduct);
        policySocialProductRepository.save(policySocialProduct);
        bean.setId(policySocialProduct.getId());
        return bean;
    }


    @Override
    public Page<PolicyProductDto> searchSocialProduct(ProductParam socialproductParam) {
        return policySocialProductMapperCustom.searchSocialProduct(socialproductParam);
    }

    @Override
    public void delSocialProduct(List<String> ids) {
        if(ids.isEmpty()){
            return;
        }
        policySocialProductRepository.deleteByIds(ids);
        policySocialItemRepository.deleteByProductIdIn(ids);
    }


    @Override
    public PolicyProductDto findOneSocialProduct(String id) {
        PolicyProductDto productDto = policySocialProductMapperCustom.findOneSocialProduct(id);
        List<PolicySocialItem> items = policySocialItemRepository.findByProductId(id);
        productDto.setItems(BeanHelper.convertList(items,PolicySocialItem.class, PolicyItemDto.class));
        return  productDto;
    }

    @Override
    @Transactional
    public PolicyItemDto createSocialItem(PolicyItemDto bean) {
        PolicySocialItem db = policySocialItemRepository.findFirstByProductIdAndItemTypeCode(bean.getProductId(),bean.getItemTypeCode());
        if(db!=null  && !db.getId().equals(bean.getId())){
            throw  new ApiException(400,"该险种类型已存在！");
        }
        PolicySocialItem item = new PolicySocialItem();

        //修改要先解除险种捆绑
        if(db!=null) {
            policySocialItemRepository.clearnGroupIdByProductId(bean.getProductId(),db.getGroupUuid());
        }
        //捆绑险种
        if(!bean.getItemGroupCodes().isEmpty()){
            String groupId =(db==null||StringUtils.isBlank(db.getGroupUuid()))? UUID.randomUUID().toString():db.getGroupUuid();
            bean.setGroupUuid(groupId);

            updateGroupIdByCodes(bean.getProductId(),bean.getItemGroupCodes(),groupId);
        }
        if(bean.getItemGroupCodes().isEmpty() && StringUtils.isNotBlank(bean.getGroupUuid())){
            bean.setGroupUuid(null);
        }
//        if(StringUtils.isNotBlank(bean.getGroupSourceItemCode())){
//            PolicySocialItem source = policySocialItemRepository.findFirstByProductIdAndItemTypeCode(bean.getProductId(),bean.getGroupSourceItemCode());
//            String groupId = source.getGroupUuid();
//            if(StringUtils.isBlank(groupId)){
//                groupId = UUID.randomUUID().toString();
//                policySocialItemRepository.save(source);
//            }
//            bean.setGroupUuid(groupId);
//        }
        BeanUtils.copyProperties(bean,item);
        policySocialItemRepository.save(item);
        BeanUtils.copyProperties(item,bean);
        return bean;
    }

    private void updateGroupIdByCodes(String productId, List<String> itemGroupCodes, String groupId) {
        policySocialItemRepository.updateGroupIdByCode(productId,itemGroupCodes,groupId);
    }

    /**
     * 更新
     * @param bean
     */
    @Override
    public void updateSocialProduct(PolicyProductDto bean) {
        PolicySocialProduct product = policySocialProductRepository.findById(bean.getId()).get();
        BeanHelper.copyProperties(bean,product);
        policySocialProductRepository.save(product);
    }


    @Override
    public void updatePolicySocialItem(PolicyItemDto bean) {
        PolicySocialItem item =  policySocialItemRepository.findById(bean.getId()).get();
        BeanHelper.copyProperties(bean,item);
        policySocialItemRepository.save(item);
    }

    @Override
    public List<String> getProductCodes(String productId) {
        return policySocialItemRepository.findItemTypeCodeByProductId(productId);
    }


    @Override
    public PolicyItemDto findOneByProductIdAnfCode(String productId, String code) {
        PolicySocialItem item =  policySocialItemRepository.findFirstByProductIdAndItemTypeCode(productId,code);
        PolicyItemDto itemDto  = new PolicyItemDto();
        itemDto.setItemTypeCode(code);
        if(item!=null) {
            BeanHelper.copyProperties(item, itemDto);
        }
        if(StringUtils.isNotBlank(itemDto.getGroupUuid())){
            itemDto.setItemGroupCodes(policySocialItemRepository.findOtherGroupCodes(productId,itemDto.getId(),itemDto.getGroupUuid()));
        }
        return itemDto;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deletecode(String productId, String code){
        PolicySocialItem firstByProductIdAndItemTypeCode = policySocialItemRepository.findFirstByProductIdAndItemTypeCode(productId, code);
        String groupUuid = firstByProductIdAndItemTypeCode.getGroupUuid();
        if(StringUtils.isNotBlank(groupUuid)){
            List<String> otherGroupCodes = policySocialItemRepository.findOtherGroupCodes(productId, firstByProductIdAndItemTypeCode.getId(), groupUuid);
            if(otherGroupCodes!=null&&otherGroupCodes.size()==1){
                policySocialItemRepository.clearnGroupIdByProductId(productId,groupUuid);
            }
        }
        return  policySocialItemRepository.deletecode( productId,  code);
    }


    @Override
    public PolicySuppRuleDto createSocialRule(PolicySuppRuleDto bean) {
        PolicySocialSuppRule rule = new PolicySocialSuppRule();
        BeanUtils.copyProperties(bean,rule);
        policySocialSuppRuleRepository.save(rule);
        bean.setId(rule.getId());
        return bean;
    }


    @Override
    public Page<PolicySuppRuleDto> searchSocialRule(String addrId, String companyId,String permissionUserId){
        return policySocialSuppRuleMapperCustom.search(addrId,companyId,permissionUserId);
    }
    @Override
    public void deleteSocialRule(List<String> ids) {
        if(ids.isEmpty()){
            return;
        }
        policySocialSuppRuleRepository.deleteByIdIn(ids);
    }


    @Override
    public PolicySuppRuleDto findSocialRule(String id) {
        return policySocialSuppRuleMapperCustom.findOne(id);
    }


    @Override
    public PolicyProductDto createAccFundProduct(PolicyProductDto bean) {
        PolicyAccfundProduct  policyAccfundProduct = new PolicyAccfundProduct();
        PolicyAddr addr = policyAddressRepository.findById(bean.getAddrId()).get();
        bean.setAddrName(addr.getAddrName());
        OptrComp optrComp  = compRepositroy.findById(bean.getOptrCompId()).get();
        bean.setOptrCompName(optrComp.getName());
        bean.setOptrCompCode(optrComp.getCode());
        BeanUtils.copyProperties(bean,policyAccfundProduct);
        policyAccfundProductRepository.save(policyAccfundProduct);
        bean.setId(policyAccfundProduct.getId());
        return bean;
    }

    @Override
    public Page<PolicyProductDto> searchAccfundProduct(ProductParam accfundproductParam) {
        return policyAccfundProductMapperCustom.searchProduct(accfundproductParam);
    }

    @Override
    public PolicyProductDto findOneAccfundProduct(String id) {
        PolicyProductDto productDto = policyAccfundProductMapperCustom.findOneProduct(id);
        List<PolicyAccfundItem> items = policyAccfundItemRepository.findByProductId(id);
        productDto.setItems(BeanHelper.convertList(items,PolicyAccfundItem.class, PolicyItemDto.class));
        return  productDto ;
    }


    @Override
    public List<String> getAccfundProductCodes(String productId) {
        return policyAccfundItemRepository.findItemTypeCodeByProductId(productId);
    }


    @Override
    public PolicyItemDto createAccfundItem(PolicyItemDto bean) {
        PolicyAccfundItem db = policyAccfundItemRepository.findFirstByProductIdAndItemTypeCode(bean.getProductId(),bean.getItemTypeCode());
        if(db!=null && (!db.getId().equals(bean.getId()))){
            throw  new ApiException(400,"该险种类型已存在！");
        }
        PolicyAccfundItem item = new PolicyAccfundItem();
        if(StringUtils.isNotBlank(bean.getGroupSourceItemCode())){
            PolicyAccfundItem source = policyAccfundItemRepository.findFirstByProductIdAndItemTypeCode(bean.getProductId(),bean.getGroupSourceItemCode());
            String groupId = source.getGroupUuid();
            if(StringUtils.isBlank(groupId)){
                groupId = UUID.randomUUID().toString();
                policyAccfundItemRepository.save(source);
            }
            bean.setGroupUuid(groupId);
        }
        BeanUtils.copyProperties(bean,item);
        policyAccfundItemRepository.save(item);
        BeanUtils.copyProperties(item,bean);
        return bean;
    }


    @Override
    public void updatePolicyAccfundItem(PolicyItemDto bean) {
        PolicyAccfundItem item =  policyAccfundItemRepository.findById(bean.getId()).get();
        BeanHelper.copyProperties(bean,item);
        policyAccfundItemRepository.save(item);
    }


    @Override
    public PolicyItemDto findOneAccfundItemByProductIdAnfCode(String productId, String code) {
        PolicyAccfundItem item =  policyAccfundItemRepository.findFirstByProductIdAndItemTypeCode(productId,code);
        PolicyItemDto itemDto  = new PolicyItemDto();
        itemDto.setItemTypeCode(code);
        if(item!=null) {
            BeanHelper.copyProperties(item, itemDto);
        }
        return itemDto;
    }
    @Override
    public  int deleteAccfunCode(String productId, String code){
        return policyAccfundItemRepository.deleteAccfunCode(productId,code);
    }


    @Override
    public void updateAccProduct(PolicyProductDto bean) {
        PolicyAccfundProduct product  = policyAccfundProductRepository.findById(bean.getId()).get();
        BeanHelper.copyProperties(bean,product);
        policyAccfundProductRepository.save(product);
    }


    @Override
    public void delAccProduct(List<String> ids) {
        if(ids.isEmpty()){
            return;
        }
        policyAccfundProductRepository.deleteByIds(ids);
        policyAccfundItemRepository.deleteByProductIdIn(ids);
    }


    @Override
    public PolicySuppRuleDto createAccfundRule(PolicySuppRuleDto bean) {
        PolicyAccfundSuppRule rule = new PolicyAccfundSuppRule();
        BeanUtils.copyProperties(bean,rule);
        policyAccfundSuppRuleRepository.save(rule);
        bean.setId(rule.getId());
        return bean;
    }


    @Override
    public Page<PolicySuppRuleDto> searchAccfundRule(String addrId, String companyId,String permissionUserId){
        return policyAccfundSuppRuleMapperCustom.search(addrId,companyId,permissionUserId);
    }


    @Override
    public void deleteAccfundRule(List<String> ids) {
        if(ids.isEmpty()){
            return;
        }
        policyAccfundSuppRuleRepository.deleteByIdIn(ids);
    }


    @Override
    public PolicySuppRuleDto findAccfundRule(String id) {
        return policyAccfundSuppRuleMapperCustom.findOne(id);
    }


    @Override
    public DisabilitiesProductDto createDisableProduct(DisabilitiesProductDto bean) {
        PolicyDisabilitiesProduct p = policyDisabilitiesProductRepository.findFirstByAddrId(bean.getAddrId());
        if(p!=null && !p.getId().equals(bean.getId())){
            throw  new ApiException(400,"参保地已绑定其他残保金");
        }
        PolicyDisabilitiesProduct  policyAccfundProduct = new PolicyDisabilitiesProduct();
        OptrComp optrComp  = compRepositroy.findById(bean.getOptrCompId()).get();
        bean.setOptrCompName(optrComp.getName());
        bean.setOptrCompCode(optrComp.getCode());
        BeanUtils.copyProperties(bean,policyAccfundProduct);
        policyDisabilitiesProductRepository.save(policyAccfundProduct);
        bean.setId(policyAccfundProduct.getId());
        return bean;
    }

    @Override
    public void delDisableProduct(List<String> ids) {
        if(ids.isEmpty()){
            return;
        }
        policyDisabilitiesProductRepository.deleteByIdIn(ids);
    }


    @Override
    public Page<DisabilitiesProductDto> searchDisableProduct(String companyId, String addrId,String permissionUserId){
        return policyDisabilitiesProductMapperCustom.search(companyId,addrId,permissionUserId);
    }
    @Override
    public DisabilitiesProductDto findOneDisableProduct(String id) {
        return policyDisabilitiesProductMapperCustom.findOneProduct(id);
    }


    @Override
    public List<String> getProductGroupdCodes(String productId,String code) {
        return policySocialItemRepository.findGroupdCodeByPid(productId,code);
    }
}
